/*
 * @Description: 状态管理及数据持久化
 * @Author: James324
 * @Date: 2023-08-18 10:58:10
 * @LastEditors: James324
 * @LastEditTime: 2024-04-01 17:02:53
 */
import piniaPersist from 'pinia-plugin-persistedstate';
import { storeReset } from './helper/storeReset';
import { STORAGE_PREFIX, GLOBAL_STATE } from '@/config';
import { login as Login, logout as Logout } from '@/api/login';
import { getUserInfo as GetUserInfo } from '@/api/user';
import { cloneDeep } from 'lodash-es';
import { getToken, removeToken, toLogin } from '@/utils';
import { Route, RouteRecordRaw } from 'vue-router';
import type { LoginRequest } from '@/api/login/model/type';
import { type UserInfo } from '@/api/user/model/type';

export const GlobalStore = defineStore(
    'GlobalState',
    () => {
        /* 登录模块 START */
        const token = ref('');
        const setToken = (data: string) => (token.value = data);
        const login = async (payload: LoginRequest) => {
            try {
                const res = await Login(payload);
                if (res.data) {
                    setToken(res.data.value);
                }
                return res;
            } catch (error) {
                return Promise.reject(error);
            }
        };
        /* 登录模块 END */

        /* 用户信息模块 START */
        const userInfo = ref<Partial<UserInfo>>({});
        const setUserInfo = (data: UserInfo) => (userInfo.value = data);

        /**
         * 获取用户信息
         */
        const getUserInfo = async () => {
            const SkeletonStore = skeletonStore();
            try {
                SkeletonStore.loading = true;
                const res = await GetUserInfo();

                if (res?.data) {
                    setUserInfo(res.data as UserInfo);
                    return res.data;
                }

                // 未获取到接口信息 清除 token, 退出登录
                Logout(getToken());
                removeToken();
                toLogin();
            } catch (error) {
                return error; // 用于全局路由守卫时网络出错动态路由注册
            } finally {
                SkeletonStore.loading = false;
            }
        };
        /* 用户信息模块 END */

        /* 路由模块 START */
        const allRoutes = ref<Route[]>([]);
        /**
         * 设置所有路由
         */
        const setAllRoutes = (constantRoutes: Route[], asyncRoutes: Route[]) => {
            const copyConstantRoutes = cloneDeep(constantRoutes);
            const oneLevelRoutes = asyncRoutes.filter(
                asyncRoute => asyncRoute.level === 1 || asyncRoute.name === 'Any'
            );

            // 子路由合并
            copyConstantRoutes.forEach((route: Route) => {
                asyncRoutes.forEach(asyncRoute => {
                    if (asyncRoute.parent && route.name === asyncRoute.parent) {
                        if (route.children) route.children.push(asyncRoute as RouteRecordRaw);
                    }
                });
            });

            allRoutes.value = [...copyConstantRoutes, ...oneLevelRoutes];
        };

        /**
         * 设置异步路由
         */
        const asyncRoutes = ref<Route>([]);
        const setAsyncRoutes = (routes: Route[]) => {
            asyncRoutes.value = routes;
        };

        /* 路由模块 END */

        return {
            token,
            userInfo,
            allRoutes,
            asyncRoutes,
            setAllRoutes,
            login,
            getUserInfo,
            setToken,
            setUserInfo,
            setAsyncRoutes
        };
    },
    {
        persist: {
            key: `${STORAGE_PREFIX}${GLOBAL_STATE}`
        }
    }
);

const pinia = createPinia();
pinia.use(storeReset);
pinia.use(piniaPersist); // 数据持久化

export default pinia;
